home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "modern.h"
- #include "stdinc.h"
- #include "zalloc.h"
- #include "zipdefs.h"
- #include "zipguts.h"
- #include "zippipe.h"
-
- void (*ziputbyte)__ARGS__((int)) = NULL;
- static unsigned bitbuff;
- static int boffset;
-
- #ifdef DEBUG
- ulg bits_sent; /* bit length of the compressed data */
- #endif
-
- #ifdef __TURBOC__
- #include <dos.h>
- #pragma warn -rvl
- #endif
- unsigned bi_reverse(code, len) /* Reverse the first len bits of a code. */
- unsigned code; /* the value to invert */
- int len; /* its bit length: 1 =< len =< 15 */
- {
- #ifdef __TURBOC__
- _DX = code; /* inline assembly ha-ha! */
- _CX = len;
- __emit__(/* all arguments must be words to avoid confusion */
- 0xC031, /* xor ax,ax */
- 0xEAD1, /* shr dx,1 */
- 0xD0D1, /* rcl ax,1 */
- 0xFAE2); /* loop $-4 */
- #else
- register unsigned res = 0;
- do res = (res << 1) | (code & 1), code>>=1; while (--len);
- return res;
- #endif
- }
- #ifdef __TURBOC__
- #pragma warn .rvl
- #endif
-
- void bi_init() /* Initialize the bit string routines. */
- {
- bitbuff = 0;
- boffset = 0;
- #ifdef DEBUG
- bits_sent = 0L;
- #endif
- }
-
- void send_bits(value, length) /* Send a value on a given number of bits. */
- unsigned value; /* value to send */
- int length; /* number of bits: length =< 16 */
- {
- #ifdef DEBUG
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- Assert(boffset < 8, "bad offset");
- bits_sent += (ulg)length;
- #endif
- bitbuff |= value << boffset;
- if ((boffset += length) >= 8) {
- putbyte(bitbuff);
- value >>= length - (boffset -= 8);
- if (boffset >= 8) {
- boffset -= 8;
- putbyte(value);
- value >>= 8;
- }
- bitbuff = value;
- }
- }
-
- /* Write out any remaining bits in an incomplete byte. */
- void bi_windup()
- {
- Assert(boffset < 8, "bad offset");
- if (boffset) {
- putbyte(bitbuff);
- boffset = 0;
- bitbuff = 0;
- #ifdef DEBUG
- bits_sent = (bits_sent+7) & ~7;
- #endif
- }
- }
-
- void bi_putsh(x)
- ush x;
- {
- putbyte(x & 255); putbyte((x>>8) & 255);
- }
-
- /* Copy a stored block to the zip file, storing first the length and its
- one's complement if requested. */
- void copy_block(buf, len, header)
- char far *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
- {
- /* align on byte boundary */
- bi_windup();
-
- if (header) {
- bi_putsh(len); bi_putsh(~len);
- #ifdef DEBUG
- bits_sent += 2*16;
- #endif
- }
- while (len--) putbyte(*buf++);
- #ifdef DEBUG
- bits_sent += (ulg)len<<3;
- #endif
- }